#include "MainWindow.h"

// We'll need some regular expression magic in this code:
#include <QRegExp>
#include <QTimer>
#include <QMessageBox>
#include <QToolTip>

// This is our MainWindow constructor (you C++ n00b)
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
    // When using Designer, you should always call setupUi(this)
    // in your constructor. This creates and lays out all the widgets
    // on the MainWindow that you setup in Designer.
    setupUi(this);

    // Make sure that we are showing the login page when we startup:
    stackedWidget->setCurrentWidget(loginPage);

    // Instantiate our socket (but don't actually connect to anything
    // yet until the user clicks the loginButton:
    socket = new QTcpSocket(this);

    // This is how we tell Qt to call our readyRead() and connected()
    // functions when the socket has text ready to be read, and is done
    // connecting to the server (respectively):
    connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
    connect(socket, SIGNAL(connected()), this, SLOT(connected()));
    connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
    connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(disconnect(QAbstractSocket::SocketError)));

    timer = new QTimer();
    connect(timer, SIGNAL(timeout()), this, SLOT(Checker()));

    helptime = 5;
    help = 3;
}

// This gets called when the loginButton gets clicked:
// We didn't have to use connect() to set this up because
// Qt recognizes the name of this function and knows to set
// up the signal/slot connection for us.
void MainWindow::on_loginButton_clicked()
{
    // Start connecting to the chat server (on port 4200).
    // This returns immediately and then works on connecting
    // to the server in the background. When it's done, we'll
    // get a connected() function call (below). If it fails,
    // we won't get any error message because we didn't connect()
    // to the error() signal from this socket.
    connectInfo->setText("Connecting to: " + serverLineEdit->text().trimmed());
    socket->connectToHost(serverLineEdit->text().trimmed(), 4300);
}

// This gets called when the user clicks the sayButton (next to where
// they type text to send to the chat room):
void MainWindow::on_sayButton_clicked()
{
    // What did they want to say (minus white space around the string):
    QString message = sayLineEdit->text().trimmed();

    // Only send the text to the chat server if it's not empty:
    if(!message.isEmpty())
    {
        socket->write(QString(message + "\n").toUtf8());
    }

    // Clear out the input box so they can type something else:
    sayLineEdit->clear();

    // Put the focus back into the input box so they can type again:
    sayLineEdit->setFocus();
}

// This function gets called whenever the chat server has sent us some text:
void MainWindow::readyRead()
{
    // We'll loop over every (complete) line of text that the server has sent us:
    while(socket->canReadLine())
    {
        // Here's the line the of text the server sent us (we use UTF-8 so
        // that non-English speakers can chat in their native language)
        QString line = QString::fromUtf8(socket->readLine()).trimmed();

        // These two regular expressions describe the kinds of messages
        // the server can send us:

        //  Normal messges look like this: "username:The message"
        QRegExp messageRegex("^([^:]+):(.*)$");

        // Any message that starts with "/users:" is the server sending us a
        // list of users so we can show that list in our GUI:
        QRegExp usersRegex("^/users:(.*)$");;

        QRegExp questRegex("^/question:(.*)$");
        QRegExp hintRegex("^/hint:(.*)$");
        QRegExp settingsRegex("^/settings:(.*)$");
        // Is this a users message:
        if(usersRegex.indexIn(line) != -1)
        {
            QStringList userScore;
            // If so, udpate our users list on the right:
            QStringList users = usersRegex.cap(1).split(",");
            userListWidget->clear();
            foreach(QString user, users)
            {
                    userScore = user.split(":");
                    new QListWidgetItem(QPixmap(":/user.png"), userScore[0] + " S:" + userScore[1] + " R:" + userScore[2], userListWidget);
            }
        }
        else if(settingsRegex.indexIn(line) != -1)
        {
            QStringList tmp;
            tmp = settingsRegex.cap(1).split("*", QString::SkipEmptyParts);
            helptime = tmp[0].toInt();
            help = tmp[1].toInt();
            overallHints->setText(QString::number(help));
            timer->start(1000);
            qDebug() << line;
        }
        else if(questRegex.indexIn(line) != -1)
        {
            QStringList tmp;
            tmp = questRegex.cap(1).split("*", QString::SkipEmptyParts);
            question->setText("(" + tmp[0] + ") " + tmp[1]);
            timer->start(1000);
            reportQuestion->show();
            if (clearChatBox->isChecked())
                roomTextEdit->clear();
        }
        else if(hintRegex.indexIn(line) != -1)
        {
            //qDebug() << line;
            QStringList tmp;
            tmp = hintRegex.cap(1).split("|", QString::SkipEmptyParts);
            if (tmp[1].toInt() == -1) //full answer case
            {
                hint->setText("<font color='red'>" + tmp[0] + "</font>");
                label_4->setText("Next question soon!");
            }
            else
            {
                givenHints->setText(tmp[1]);
                hint->setText(tmp[0]);
                if (tmp[1].toInt() == help)
                    label_4->setText("Next <b>question</b> in:");
                else
                    label_4->setText("Next hint in:");
                hintNum->display(helptime);
            }
            timer->start(1000);
        }
        // Is this a normal chat message:
        else if(messageRegex.indexIn(line) != -1)
        {
            //qDebug() << line;
            // If so, append this message to our chat box:
            QString user = messageRegex.cap(1);
            QString message = messageRegex.cap(2);

            roomTextEdit->append("<b>" + user + "</b>: " + message);
        }
    }
}

// This function gets called when our socket has successfully connected to the chat
// server. (see the connect() call in the MainWindow constructor).
void MainWindow::connected()
{
    // Send our username to the chat server.
    socket->write(QString("/me:" + userLineEdit->text() + "\n").toUtf8());

    // And flip over to the chat page:
    stackedWidget->setCurrentWidget(chatPage);
}

// This function gets called when our socket has successfully connected to the chat
// server. (see the connect() call in the MainWindow constructor).
void MainWindow::disconnected()
{
    roomTextEdit->clear();
    stackedWidget->setCurrentWidget(loginPage);
    connectInfo->setText("Disconnected. (Invalid Username)");
}

void MainWindow::disconnect(QAbstractSocket::SocketError a)
{
    if (a == QAbstractSocket::HostNotFoundError)
        connectInfo->setText("Disconnected. (Invalid IP)");
    else if (a == QAbstractSocket::SocketTimeoutError)
        connectInfo->setText("Disconnected. (Timeout)");

}

void MainWindow::Checker()
{
    if (hintNum->intValue() >= 0)
        hintNum->display(hintNum->intValue()-1);
}
void MainWindow::Checker2()
{
    /*if (questNum->intValue() == 0)textEdit
        return;

    if (questNum->intValue() == 5)
        questNum->setStyleSheet("* { background: red }");
    else if (questNum->intValue() == helptime*help)
        questNum->setStyleSheet("* { background: white }");

    questNum->display(questNum->intValue()-1);*/
}

void MainWindow::on_reportQuestion_clicked()
{
    socket->write(QString("BAD_QUESTION\n").toUtf8());

    QMessageBox::warning(this, "Reported!", "This question was reported.");
    reportQuestion->hide();
}

void MainWindow::on_suggestQuestion_clicked()
{
    stackedWidget->setCurrentWidget(questPage);
}

void MainWindow::on_suggestQuestion_2_clicked()
{
    if (questionEdit->toPlainText().contains('*'))
        QMessageBox::warning(this, "Error!", "Question can't contain * symbol.");
    else if (questionEdit->toPlainText().isEmpty())
        QMessageBox::warning(this, "Error!", "Question field must be filled.");
    else if (answerEdit->text().isEmpty())
        QMessageBox::warning(this, "Error!", "Answer field must be filled.");

    if (questionEdit->toPlainText().contains('*') || questionEdit->toPlainText().isEmpty() || answerEdit->text().isEmpty())
        return;

    socket->write(QString("/QUEST:" + questionEdit->toPlainText().trimmed() + "Author: " + userLineEdit->text().trimmed() + "*" + answerEdit->text().trimmed() + "\n").toUtf8());
    answerEdit->clear();
    questionEdit->clear();
    stackedWidget->setCurrentWidget(chatPage);
}

void MainWindow::on_pushButton_clicked()
{
    answerEdit->clear();
    questionEdit->clear();
    stackedWidget->setCurrentWidget(chatPage);
}
